////////////////////
// Permissions
////////////////////

import { events } from "./events";
import { runtime } from "./runtime";

/**
 * Use the `Browser.permissions` API to request declared optional permissions at run time rather than install time, so users understand why the permissions are needed and grant only those that are necessary.
 */
export namespace permissions {
    export interface Permissions {
        /** The list of host permissions, including those specified in the `optional_permissions` or `permissions` keys in the manifest, and those associated with [Content Scripts](https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts). */
        origins?: string[];
        /** List of named permissions (does not include hosts or origins). */
        permissions?: runtime.ManifestPermissions[];
    }

    export interface AddHostAccessRequest {
        /** The id of a document where host access requests can be shown. Must be the top-level document within a tab. If provided, the request is shown on the tab of the specified document and is removed when the document navigates to a new origin. Adding a new request will override any existent request for `tabId`. This or `tabId` must be specified. */
        documentId?: string;
        /** The URL pattern where host access requests can be shown. If provided, host access requests will only be shown on URLs that match this pattern. */
        pattern?: string;
        /** The id of the tab where host access requests can be shown. If provided, the request is shown on the specified tab and is removed when the tab navigates to a new origin. Adding a new request will override an existent request for `documentId`. This or `documentId` must be specified. */
        tabId?: number;
    }

    /**
     * Adds a host access request. Request will only be signaled to the user if extension can be granted access to the host in the request. Request will be reset on cross-origin navigation. When accepted, grants persistent access to the site’s top origin
     * @since Chrome 133
     */
    export function addHostAccessRequest(request: AddHostAccessRequest, callback?: () => void): Promise<void> {
        return Wab.callFunctionAsync({ funcName: 'permissions.addHostAccessRequest', request }).then(callback)
    }

    /**
     * Checks if the extension has the specified permissions.
     * Can return its result via Promise in Manifest V3 or later since Chrome 96.
     */
    export function contains(permissions: Permissions, callback?: (result: boolean) => void): Promise<boolean> {
        return Wab.callFunctionAsync({ funcName: 'permissions.contains', permissions }).then(res => {
            callback?.(res)
            return res
        })
    }

    /**
     * Gets the extension's current set of permissions.
     * Can return its result via Promise in Manifest V3 or later since Chrome 96.
     */
    export function getAll(callback?: (permissions: Permissions) => void): Promise<Permissions> {
        return Wab.callFunctionAsync({ funcName: 'permissions.getAll' }).then(res => {
            callback?.(res)
            return res
        })
    }

    /**
     * Requests access to the specified permissions, displaying a prompt to the user if necessary.
     * These permissions must either be defined in the optional_permissions field of the manifest or be required permissions that were withheld by the user.
     * Paths on origin patterns will be ignored.
     * You can request subsets of optional origin permissions; for example, if you specify `*://*\/*` in the `optional_permissions` section of the manifest, you can request `http://example.com/`.
     * If there are any problems requesting the permissions, {@link runtime.lastError} will be set.
     * Can return its result via Promise in Manifest V3 or later since Chrome 96.
     */
    export function request(permissions: Permissions, callback?: (granted: boolean) => void): Promise<boolean> {
        return Wab.callFunctionAsync({ funcName: 'permissions.request', permissions }).then(res => {
            callback?.(res)
            return res
        })
    }

    /**
     * Removes access to the specified permissions. If there are any problems removing the permissions, {@link runtime.lastError} will be set.
     * Can return its result via Promise in Manifest V3 or later since Chrome 96.
     */
    export function remove(permissions: Permissions, callback?: (removed: boolean) => void): Promise<boolean> {
        return Wab.callFunctionAsync({ funcName: 'permissions.remove', permissions }).then(res => {
            callback?.(res)
            return res
        })
    }

    export interface RemoveHostAccessRequest {
        /** The id of a document where host access request will be removed. Must be the top-level document within a tab. This or `tabId` must be specified. */
        documentId?: string;
        /** The URL pattern where host access request will be removed. If provided, this must exactly match the pattern of an existing host access request. */
        pattern?: string;
        /** The id of the tab where host access request will be removed. This or `documentId` must be specified. */
        tabId?: number;
    }

    /**
     * Removes a host access request, if existent.
     * @since Chrome 133
     */
    export function removeHostAccessRequest(request: RemoveHostAccessRequest, callback?: () => void): Promise<void> {
        return Wab.callFunctionAsync({ funcName: 'permissions.removeHostAccessRequest', request }).then(() => {
            callback?.()
        })
    }

    /** Fired when access to permissions has been removed from the extension. */
    export const onRemoved: events.EventDispatcher<(permissions: Permissions) => void> = new events.EventDispatcher();

    /** Fired when the extension acquires new permissions. */
    export const onAdded: events.EventDispatcher<(permissions: Permissions) => void> = new events.EventDispatcher();
}